<template>
    <div>
        <span v-if="!ui && text">
            {{itemProvince&&itemProvince.value}}{{itemCity&&itemCity.value}}{{itemArea&&itemArea.value}}{{itemTown&&itemTown.value}}
        </span>


        <select :class="className" v-model="nowProvince" v-if="!text && !ui && province">
            <option value="" v-if="blank">{{lang.pleaseSelect}}</option>
            <option :value="p.key" v-for="p in listProvince">{{p.value}}</option>
        </select>
        <select :class="className" v-model="nowCity" v-if="!text && !ui && city && haveCity">
            <option value="" v-if="blank">{{lang.pleaseSelect}}</option>
            <option :value="c.key" v-for="c in listCity">{{c.value}}</option>
        </select>
        <select :class="className" v-model="nowArea" v-if="!text && !ui && ((area && city) || !haveCity)">
            <option value="" v-if="blank">{{lang.pleaseSelect}}</option>
            <option :value="a.key" v-for="a in listArea">{{a.value}}</option>
        </select>
        <select :class="className" v-model="nowTown" v-if="!text && !ui && town && area && city">
            <option value="" v-if="blank">{{lang.pleaseSelect}}</option>
            <option :value="t.key" v-for="t in listTown">{{t.value}}</option>
        </select>



        <!-- selector mode -->
        <div class="caller-container" @click.stop.prevent="showDropdown(true)" v-if="ui" ref="caller">
            <slot></slot>
        </div>
        <v-dropdown v-if="ui" ref="dropdown">
            <div class="rg-header">
                <h3>
                    <span v-show="!itemProvince&&!itemCity&&!itemArea&&!itemTown">行政区划选择器</span>
                    <div v-show="itemProvince||itemCity||itemArea||itemTown" class="rg-header-selected">
                        {{itemProvince&&itemProvince.value}}{{itemCity&&itemCity.value}}{{itemArea&&itemArea.value}}{{itemTown&&itemTown.value}}
                    </div>
                </h3>

                <button type="button" title="清除选择" @click="clear" class="rg-removeall-button" >
                    <i class="iconfont icon-removeall"></i>
                </button>
                <button type="button" title="完成" @click="showDropdown(false)" class="rg-done-button" >
                    <i class="iconfont icon-selected"></i>
                </button>
            </div>
            <div class="rg-search" v-if="search">
                <input type="text" autocomplete="off" ref="input"
                       v-model.trim="query"
                       class="rg-input">
            </div>
            <div class="rg-level-tabs" >
                <ul>
                    <li v-for="tab,index in levels" v-if="checkAvailable(index)">
                        <a href="javascript:void(0);"
                           :tab_id="'selectmenu_tab_' + (index+1)"
                           :data_index="index"
                           @click="levelIndex = index"
                           :class="{active:index === levelIndex}">{{tab.title}}</a>
                    </li>
                </ul>
            </div>
            <div class="rg-results-container">
                <ul class="rg-results">
                    <li :class="{'rg-item':true,active:matchItem(item)}"
                        @click="itemSelect(item)"
                        v-for="item,index in list">{{item.value}}</li>
                    <li class="rg-message-box" v-show="list.length === 0">无匹配项目</li>
                </ul>
            </div>
        </v-dropdown>
    </div>
</template>

<script>
    import Dropdown from './Dropdown';
    import {srcProvince, srcCity, srcArea} from "./region.js";
    import language from './language';

    export default {
        name: "v-region",
        components: {
            'v-dropdown': Dropdown
        },
        props: {
            blank: {
                type: Boolean,
                default: true
            },
            province: {
                type: Boolean,
                default: true
            },
            city: {
                type: Boolean,
                default: true
            },
            area: {
                type: Boolean,
                default: true
            },
            town: {
                type: Boolean,
                default: false
            },
            i18n: {
                type: String,
                default: 'cn'
            },
            selected: Object,
            ui: {
                type: Boolean,
                default: false
            },
            search: {
                type: Boolean,
                default: true
            },
            text: {
                type: Boolean,
                default: false
            }
        },
        data(){
            return {
                listProvince: [],
                listCity: [],
                listArea: [],
                listTown: [],
                nowProvince: '',
                nowCity: '',
                nowArea: '',
                nowTown: '',

                haveCity: true,// is municipality
                className: '',
                lang: {},
                init: this.selected,
                pauseWatch: false,

                //ui mode data
                query: '',
                levels: [
                    {index:0,title:'省/直辖市'},
                    {index:1,title:'市'},
                    {index:2,title:'区/县'},
                    {index:3,title:'乡/镇/街道'}
                ],
                levelIndex: -1,
                list: [],

                //return data
                itemProvince: null,
                itemCity: null,
                itemArea: null,
                itemTown: null
            };
        },
        watch:{
            /**
             * region search(ui mode)
             * search region description first, if no result, then search region key
             * @param value
             */
            query(value){
                let list = this.getList(this.levelIndex),tmp = [];
                tmp = list.filter(val=>val.value.toLowerCase().includes(value.toLowerCase()));
                if(tmp.length === 0) tmp = list.filter(val=>val.key.includes(value));
                this.list = tmp;
            },
            nowProvince(value){
                if(this.pauseWatch) return;
                if(this.city){
                    if(this.listArea.length) this.listArea.splice(0, this.listArea.length);
                    this.listCity = srcCity.filter(val=>{
                        let num = Number.parseInt(value);
                        return (val.key - num) < 1e4 && (val.key%num) < 1e4;
                    });

                    this.nowCity = '';
                    if(!this.haveCity) this.nowArea = '';

                    this.itemProvince = this.listProvince.find(val=>val.key === value);

                    this.haveCity = this.listCity.length ? true : false;

                    this.$nextTick(()=>{
                        if(!this.haveCity && this.area) this.changeCity();
                        else{
                            this.initSelected(2);
                        }

                        if(this.ui) this.levelIndex = this.haveCity ? 1 : 2;
                    });
                }

                this.changeValues();
            },
            nowCity(value){
                if(this.pauseWatch) return;
                this.changeCity();

                this.itemCity = this.listCity.find(val=>val.key === value);

                if(this.ui) this.levelIndex = 2;

                this.changeValues();
            },
            nowArea(value){
                if(this.pauseWatch) return;
                let that = this;
                if(value && this.town){
                    let towns = null, tmpArr = [];
                    try{
                        towns = require(`./town/${value}.json`);
                    }catch (e) {}
                    if(towns && Object.keys(towns).length){
                        for(let d in towns){
                            tmpArr.push({key: d, value: towns[d]})
                        }
                    }
                    this.listTown = tmpArr;
                }else this.listTown = [];

                if(this.town) this.nowTown = '';

                this.itemArea = this.listArea.find(val=>val.key === value);
                this.initSelected(4);

                if(this.ui && this.town) this.levelIndex = 3;

                this.changeValues();
            },
            nowTown(value){
                if(this.pauseWatch) return;
                this.itemTown = this.listTown.find(val=>val.key === value);

                this.changeValues();
            },
            /**
             * init region selected
             */
            selected: {
                handler(val){
                    if(val && Object.keys(val).length){
                        this.init = val;
                        //if(val.province) this.nowProvince = val.province;
                        this.initSelected(1);
                    }
                },
                deep: true
            },
            /**
             * watch current region group
             * @param val
             */
            levelIndex(val){
                this.list = this.getList(val);
            }
        },
        methods:{
            changeCity(){
                if(this.area || (!this.haveCity && this.province)){
                    if((this.haveCity && !this.nowCity) || (!this.haveCity && !this.nowProvince)){
                        this.listArea = [];
                    }else{
                        let thisCity = Number.parseInt(this.haveCity?this.nowCity:this.nowProvince);
                        let range = this.haveCity ? 100 : 1000;
                        this.listArea = srcArea.filter(val=>(val.key - thisCity) < range && val.key%thisCity < range);
                    }
                    this.nowArea = '';
                }
                this.initSelected(3);
            },
            changeValues(){
                this.$nextTick(()=>{
                    this.$emit('values', {
                        province: this.itemProvince,
                        city: this.itemCity,
                        area: this.itemArea,
                        town: this.itemTown
                    });
                });
            },
            initSelected(level){
                let that = this, ini = this.init, count = 0;
                if(ini){
                    switch(level){
                        case 1://province
                            if(that.province && ini.province) that.nowProvince = ini.province;
                            break;
                        case 2://city
                            if(that.city && ini.city) that.nowCity = ini.city;
                            break;
                        case 3://area
                            if(that.area && ini.area) that.nowArea = ini.area;
                            break;
                        case 4://town
                            if(that.town && ini.town) that.nowTown = ini.town;
                            break;
                    }
                    if(that.province && ini.province) count++;
                    if(that.city && (ini.city || (!ini.city && !that.haveCity && that.area && init.area))) count++;
                    if(that.area && ini.area) count++;
                    if(that.town && ini.town) count++;
                    if(level === count) this.init = null;
                }
            },
            getList(val){
                let list = [];
                switch(val){
                    case 0:
                        list = this.listProvince;
                        break;
                    case 1:
                        list = this.listCity;
                        break;
                    case 2:
                        list = this.listArea;
                        break;
                    case 3:
                        list = this.listTown;
                        break;
                }
                return list;
            },
            //check level available
            checkAvailable(index){
                let val = false;
                switch(index){
                    case 0://province
                        if(this.province) val = true;
                        break;
                    case 1://city
                        if(this.city && this.haveCity) val = true;
                        break;
                    case 2://area
                        if(this.area) val = true;
                        break;
                    case 3://town
                        if(this.town) val = true;
                        break;
                }
                return val;
            },
            matchItem(item){
                return item.key === this.nowProvince ||
                        item.key === this.nowCity ||
                        item.key === this.nowArea ||
                        item.key === this.nowTown;
            },
            itemSelect(item){
                let that = this;
                switch(this.levelIndex){
                    case 0:
                        this.nowProvince = item.key;
                        this.itemProvince = item;
                        break;
                    case 1:
                        this.nowCity = item.key;
                        this.itemCity = item;
                        break;
                    case 2:
                        this.nowArea = item.key;
                        this.itemArea = item;
                        break;
                    case 3:
                        this.nowTown = item.key;
                        this.itemTown = item;
                        break;
                }
            },
            showDropdown(val){
                if(typeof(val) === 'boolean') {
                    let that = this;
                    this.$refs.dropdown.$emit('show', val, this.$refs.caller);
                    if(val) {
                        this.query = '';
                        this.$nextTick(()=>that.$refs.input.focus({preventScroll:true}));
                    }
                }
            },
            clear(){
                let that = this;
                this.pauseWatch = true;
                this.nowProvince = '';
                this.nowCity = '';
                this.nowArea = '';
                this.nowTown = '';
                this.itemProvince = null;
                this.itemCity = null;
                this.itemArea = null;
                this.itemTown = null;
                this.listCity = [];
                this.listArea = [];
                this.listTown = [];
                this.levelIndex = 0;
                this.$nextTick(()=>{
                    that.pauseWatch = false;
                    that.changeValues();
                });
            }
        },
        beforeMount(){
            this.lang = language[this.i18n];
        },
        mounted(){
            let that = this;
            //sort by length and code
            this.listProvince = this.ui?srcProvince.concat().sort((a,b)=>{
                let gap = a.value.length - b.value.length;
                return gap === 0?Number(a.key)-Number(b.key):gap;
            }):srcProvince.concat();
            this.className = this.$el.className;
            this.$el.className = 'v-region';

            if(this.selected && this.selected.province) this.nowProvince = this.selected.province;
            if(this.ui) this.levelIndex = 0;
        }
    }
</script>

<style lang="scss">
    div.v-region {
        display: inline-block;
        select {
            width: auto;
            display: inline-block;
            overflow: hidden;
            box-sizing: content-box;
            padding: 0 12px;
            margin-right: 5px;
        }
        div.caller-container{ display: inline-block; }
        div.rg-header {
            width: 400px;
            & > h3 {
                margin: 6px 80px 10px 10px;
                text-align: left;
                color: #24292e;
                font-size: 16px;
                white-space: nowrap;
                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
                .rg-header-selected{
                    white-space: nowrap;
                    text-overflow: ellipsis;
                    -o-text-overflow: ellipsis;
                    overflow: hidden;
                    font-size: 14px;
                    max-width: 310px;
                }
            }
            button{
                position: absolute;
                -webkit-appearance: none;
                padding: 0;
                cursor: pointer;
                background: 0 0;
                border: 0;
                outline: none;
                line-height: 100%;
                color: #999999;
                top: 3px;
                font-size: 20px;
                &.rg-close-button { right: 10px;font-size: 26px;top:0;font-weight: 300; }
                &.rg-removeall-button { right: 32px; }
                &.rg-done-button { /*right: 54px;*/right: 8px;top: 4px;i{font-size: 18px;} }
                &:hover { color: black; }
            }
        }
        div.rg-search {
            padding: 2px 10px 10px;
            .rg-input {
                display: block;
                background-color: white;
                margin: 0 !important;
                width: 100%;

                font-size: 14px;
                line-height: 20px;
                min-height: 20px;
                padding: 4px 6px;
                vertical-align: middle;
                box-sizing: border-box;

                outline: none !important;
                height: 30px;

                border-radius: 2px;
                border: 1px solid #dddddd;
                -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
                -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
                box-shadow: inset 0 1px 1px rgba(0,0,0,.075);

                transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
                &:focus { border: 1px solid #bbbbbb;box-shadow: 0 0 0 3px rgba(150,150,150, 0.2); }
            }
        }
        /* group type */
        div.rg-level-tabs {
            padding: 0 10px;border-bottom: 1px solid #E6E7E7;
            ul {
                position: relative;
                bottom: -1px;
                padding: 0;
                margin: 0;
                text-align: left;
                li {
                    display: inline-block;
                    a {
                        display: inline-block;
                        padding: 7px 10px 3px;
                        font-size: 14px;
                        color: #6a737d;
                        text-decoration: none;
                        cursor: pointer;
                        line-height: 100%;
                        background: transparent;
                        border: 1px solid transparent;
                        border-radius: 3px 3px 0 0;
                        font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
                        &.active {
                            color: #24292e;
                            background-color: #fff;
                            border-color: #dfe2e5;
                            border-bottom-color: #fff;
                            /*font-weight: bold;*/
                        }
                    }
                }
            }
        }

        div.rg-results-container{
            background-color: white;
            list-style: none;
            margin: 0;
            padding: 0;
            position: relative;
            width: 100%;
            overflow-y: auto;
            overflow-x: hidden;
            clear: both;
            border-bottom-left-radius: 2px;
            border-bottom-right-radius: 2px;
            ul.rg-results {
                background-color: white;
                list-style: none;
                margin: 0;
                padding: 5px;
                /*height: 300px;*/
                width: 400px;
                li.rg-item {
                    display: inline-block;
                    border: 1px solid white;
                    border-radius: 2px;
                    margin-right: 5px;
                    color: #666666;
                    &:hover{
                        border: 1px solid #DDDDDD;
                        box-shadow: 0 1px 8px rgba(0,0,0,0.2);
                        -moz-box-shadow: 0 1px 8px rgba(0,0,0,0.2);
                        -webkit-box-shadow: 0 1px 8px rgba(0,0,0,0.2);
                        color: black;
                        background-color: #F6F6F6;
                    }
                    &.active { border: 1px solid #666666;background-color: #DDDDDD; }
                }
                & > li {
                    /*height: auto;
                    line-height: 1;*/
                    margin: 0;
                    overflow: hidden;
                    padding: 3px 10px;
                    position: relative;
                    text-align: left;
                    white-space: nowrap;
                    font-size: 14px;
                    color: black;
                    cursor : pointer;
                    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
                    &.rg-message-box {
                        height: 30px;
                        line-height: 30px;
                        text-align: center;
                        box-sizing: content-box;
                        font-size: 14px;
                        cursor: default;
                        i { font-size: 18px; }
                    }
                }
            }
        }
        div.rg-selected-container {
            /*padding: 5px 16px 7px;*/
            border-top: 1px solid #E6E7E7;
            background-color: white;
            border-bottom-left-radius: 2px;
            border-bottom-right-radius: 2px;
            display: inline-block;
            width: 400px;
            position: relative;
            div.rg-selected-content{
                /*margin-right: 30px;*/
                display: inline-block;
                width: 350px;
            }
            div.rg-done {
                height: 100%;
                width: 50px;
                display: inline-block;
                text-align: center;
                position: absolute;
                top: 0;
                bottom: 0;
                right: 0;
                i{
                    line-height: 1;
                    font-size: 20px;
                    top: 50%;
                    position: absolute;
                    margin-top: -10px;
                }
            }
        }
    }


    /* icons */
    @font-face {font-family: "iconfont";
        src: url(''); /* IE9*/
        src: url('') format('embedded-opentype'), /* IE6-IE8 */
        url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
        url('') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
        url('') format('svg'); /* iOS 4.1- */
    }

    .iconfont {
        font-family:"iconfont" !important;
        font-size:14px;
        font-style:normal;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
    }
    .icon-warn:before { content: "\e663"; }
    .icon-selectall:before { content: "\e722"; }
    .icon-selected:before { content: "\e72e"; }
    .icon-removeall:before { content: "\e74b"; }
    .icon-back:before { content: "\e627"; }
</style>